package com.yyfax.infrastructure.upgrade;

import com.yyfax.common.CLog;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by HenryZhang on 2016/11/23.
 * Copyright © 2016 www.yyfax.com. All Rights Reserved.
 */
public class NetworkPorter {
	private static final String TAG = "NetworkPorter";

    public static class DownloadInfo {
        public String content;
        public long modifiedTime;
    }

    public static void downloadToFile(String url, File output) {
        HttpURLConnection con = null;
        InputStream is = null;
        DownloadInfo info = new DownloadInfo();
        BufferedOutputStream bos = null;
        try {
            CLog.d(TAG, "Connect to url: " + url);
            con = (HttpURLConnection) new URL(url).openConnection();
            con.setConnectTimeout(5000);
            con.setReadTimeout(8000);
            con.setInstanceFollowRedirects(true);
            CLog.d(TAG, "Download url: " + url);
            // download from network
            is = con.getInputStream();

            byte[] buffer = new byte[4096];
            bos = new BufferedOutputStream(new FileOutputStream(output));
            while (true) {
                int read = is.read(buffer);
                if (read == -1) break;
                bos.write(buffer, 0, read);
            }
            CLog.d(TAG, "Download complete: " + url + " -> " + output);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (con != null) con.disconnect();

            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static DownloadInfo downloadIfModified(String url, String params, String charsetName, long localModifiedTime) {
        return downloadIfModified(url, params, charsetName, localModifiedTime, true);
    }

    public static DownloadInfo downloadIfModified(String url, String params, String charsetName, long localModifiedTime, boolean followRedirect) {
        HttpURLConnection conn = null;
        InputStream is = null;
        DownloadInfo info = new DownloadInfo();
        try {
            CLog.d(TAG, "Connect to url: " + url);
            conn = (HttpURLConnection) new URL(url).openConnection();
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type", "application/json");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(10000);
            conn.setInstanceFollowRedirects(followRedirect);

			OutputStream out = conn.getOutputStream();//向服务器写数据
			out.write(params.getBytes());
			out.flush();
			out.close();

			int responseCode = conn.getResponseCode();
			CLog.i(TAG, "responseCode = " + responseCode);
			if (responseCode != 200) {
				return info;
			}

            final long lastModifiedTime = conn.getLastModified();
            CLog.d(TAG, "Last modified time in server: " + lastModifiedTime);
            if (localModifiedTime == 0 || lastModifiedTime == 0 || localModifiedTime != lastModifiedTime) {
                CLog.d(TAG, "Ready to download from network");
                is = conn.getInputStream();
                info.content = NetworkPorter.convertStreamToString(is, charsetName);
                info.modifiedTime = lastModifiedTime;
                CLog.d(TAG, "Download complete: " + url);
            }
            else {
                CLog.d(TAG, "The config file isn't modified in server");
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (conn != null) conn.disconnect();
        }
        return info;
    }

	// Given a URL, establishes an HttpUrlConnection and retrieves
	// the web page content as a InputStream, which it returns as
	// a string.
	@SuppressWarnings("UnusedDeclaration")
    public static String downloadUrl(String target) throws IOException {
		InputStream is = null;
		try {
			URL url = new URL(target);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setInstanceFollowRedirects(true);
			conn.setReadTimeout(10000 /* milliseconds */);
			conn.setConnectTimeout(15000 /* milliseconds */);
			conn.setRequestMethod("GET");
			conn.setDoInput(true);
			// Starts the query
			conn.connect();
			int response = conn.getResponseCode();
			CLog.d(TAG, "The response is: " + response);
			is = conn.getInputStream();

			// Convert the InputStream into a string
            return readIt(is, 1024);

			// Makes sure that the InputStream is closed after the app is
			// finished using it.
		} finally {
			if (is != null) {
				is.close();
			}
		}
	}

	// Reads an InputStream and converts it to a String.
	public static String readIt(InputStream stream, int len) throws IOException {
		Reader reader = new InputStreamReader(stream, "UTF-8");
		char[] buffer = new char[len];
		int actual_len = reader.read(buffer);
		if (actual_len > 0 && actual_len < len) {
			return new String(buffer, 0, actual_len);
		}
		return null;
	}

	public static String convertStreamToString(InputStream is, String encoding) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, encoding));
            StringBuilder sb = new StringBuilder();

            String line;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return sb.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
	}
}
